package com.chang.demo.utils;

import com.chang.demo.bean.RequestParamBean;
import com.chang.demo.bean.TsServiceBean;
import com.chang.demo.bean.TsServiceMethodBean;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.HashMap;

public class ControllerParser {
    @Value("${controller.parser.path}")
    public String controllerPath;
    private HashMap<String, TsServiceBean> tsServiceMap = new HashMap();

    public void parse (File file, String relativePath) throws ClassNotFoundException {
        // 提取文件名
        String fileName = file.getName();
        String className = fileName.substring(0, fileName.lastIndexOf('.'));
        String realControllerPath = controllerPath + relativePath + "." + className;
        Class clazz = Class.forName(realControllerPath);
//        String name = clazz.getName();
        parseClass(clazz);
    }

    public void parseClass (Class clazz) {
        Api clazzAnnotation = (Api) clazz.getAnnotation(Api.class);
        RequestMapping clazzReqMppAnno = (RequestMapping) clazz.getAnnotation(RequestMapping.class);
        String value = clazzAnnotation.value();
        String[] tags = clazzAnnotation.tags();
        String[] path = clazzReqMppAnno.path();
        String realPath = path.length > 0 ? path[0] : "";
        System.out.println("解析模块: " + realPath + " " + value + String.join(",", tags));
        TsServiceBean tsServiceBean = new TsServiceBean();
        tsServiceBean.setServiceName(clazz.getName().replace("Controller", "Service"));
        tsServiceBean.serviceMethodBeanList = new ArrayList<>();
        tsServiceMap.put(tsServiceBean.serviceName, tsServiceBean);
        Method[] methods = clazz.getDeclaredMethods();
        // 解析方法
        for (Method method : methods) {
            parseMethod(method, tsServiceBean);
        }
    }
    public void parseMethod (Method method, TsServiceBean tsServiceBean) {
        TsServiceMethodBean serviceMethodBean = new TsServiceMethodBean();
        // 解析path
        RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
        PostMapping postMapping = method.getAnnotation(PostMapping.class);
        GetMapping getMapping = method.getAnnotation(GetMapping.class);
        PutMapping putMapping = method.getAnnotation(PutMapping.class);
        DeleteMapping deleteMapping = method.getAnnotation(DeleteMapping.class);
        Class<?> returnType = method.getReturnType();

        System.out.println("正在解析方法: " + method.getName());

        String path = "";
        RequestMethod requestMethod = RequestMethod.GET;
        if (requestMapping != null) {
            path =( requestMapping.path().length > 0) ? requestMapping.path()[0] : requestMapping.value()[0];
            requestMethod = requestMapping.method()[0];
        }
        if (postMapping != null) {
             path =( requestMapping.path().length > 0) ? requestMapping.path()[0] : requestMapping.value()[0];
            requestMethod = RequestMethod.POST;
        }
        if (getMapping != null) {
             path =( requestMapping.path().length > 0) ? requestMapping.path()[0] : requestMapping.value()[0];
            requestMethod = RequestMethod.GET;
        }
        if (deleteMapping != null) {
             path =( requestMapping.path().length > 0) ? requestMapping.path()[0] : requestMapping.value()[0];
            requestMethod = RequestMethod.DELETE;
        }
        if (putMapping != null) {
             path =( requestMapping.path().length > 0) ? requestMapping.path()[0] : requestMapping.value()[0];
            requestMethod = RequestMethod.PUT;
        }
        serviceMethodBean.setRequestMethod(requestMethod);
        serviceMethodBean.setName(method.getName());
        serviceMethodBean.setRequestUrl(path);
        serviceMethodBean.setReturnType(returnType);

        System.out.println(requestMethod + " " + path);
        System.out.println(returnType.getTypeName());

        // 解析参数
        Parameter[] parameters = method.getParameters();
        for (Parameter parameter : parameters) {
            RequestBody requestBody = parameter.getAnnotation(RequestBody.class);
            RequestParam requestParam = parameter.getAnnotation(RequestParam.class);
            PathVariable pathVariable = parameter.getAnnotation(PathVariable.class);
            Class<?> parameterType = parameter.getType();
//            String parameterName = parameter.getName();
            String parameterTypeName = parameterType.getName();
            if (requestBody != null) {
                System.out.println("检测到请求体参数， 类型: " + parameterTypeName);
                serviceMethodBean.setRequestBodyType(parameterType);
            }
            if (requestParam != null) {
                String paramName = requestParam.value();
                System.out.println("检测到query参数，名称: " + requestParam.value() + ", 类型: " + parameterTypeName);
                RequestParamBean requestParamBean = new RequestParamBean();
                requestParamBean.setName(paramName);
                serviceMethodBean.addParam(requestParamBean);
            }
            if (pathVariable != null) {
                System.out.println("检测到路径参数，名称: " + pathVariable.value());
                serviceMethodBean.addPathParam(pathVariable.value());
            }

        }



    }
}
